// 日期工具函数

/**
 * 格式化日期
 * @param {Date|string} date - 日期对象或日期字符串
 * @param {string} format - 格式字符串，如 'YYYY-MM-DD'
 * @returns {string} 格式化后的日期字符串
 */
export const formatDate = (date, format = 'YYYY-MM-DD') => {
  const d = new Date(date);
  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  const hours = String(d.getHours()).padStart(2, '0');
  const minutes = String(d.getMinutes()).padStart(2, '0');
  const seconds = String(d.getSeconds()).padStart(2, '0');

  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds);
};

/**
 * 获取今天的日期字符串 (YYYY-MM-DD)
 */
export const getToday = () => {
  return formatDate(new Date(), 'YYYY-MM-DD');
};

/**
 * 获取当前周的开始和结束日期
 * @param {Date} date - 基准日期，默认为今天
 * @param {string} weekStartDay - 周起始日，'sunday' 或 'monday'
 * @returns {{weekStart: string, weekEnd: string}}
 */
export const getWeekRange = (date = new Date(), weekStartDay = 'monday') => {
  const d = new Date(date);
  const day = d.getDay();
  
  let diff;
  if (weekStartDay === 'monday') {
    diff = day === 0 ? -6 : 1 - day; // 如果周日，向前推6天
  } else {
    diff = -day; // 周日为起始
  }
  
  const weekStart = new Date(d);
  weekStart.setDate(d.getDate() + diff);
  
  const weekEnd = new Date(weekStart);
  weekEnd.setDate(weekStart.getDate() + 6);
  
  return {
    weekStart: formatDate(weekStart, 'YYYY-MM-DD'),
    weekEnd: formatDate(weekEnd, 'YYYY-MM-DD'),
  };
};

/**
 * 获取当前月份字符串 (YYYY-MM)
 */
export const getCurrentMonth = (date = new Date()) => {
  return formatDate(date, 'YYYY-MM');
};

/**
 * 判断是否为同一天
 */
export const isSameDay = (date1, date2) => {
  return formatDate(date1, 'YYYY-MM-DD') === formatDate(date2, 'YYYY-MM-DD');
};

/**
 * 判断是否为同一周
 */
export const isSameWeek = (date1, date2, weekStartDay = 'monday') => {
  const week1 = getWeekRange(date1, weekStartDay);
  const week2 = getWeekRange(date2, weekStartDay);
  return week1.weekStart === week2.weekStart;
};

/**
 * 判断是否为同一月
 */
export const isSameMonth = (date1, date2) => {
  return formatDate(date1, 'YYYY-MM') === formatDate(date2, 'YYYY-MM');
};

/**
 * 获取日期之间的天数差
 */
export const getDaysDiff = (date1, date2) => {
  const d1 = new Date(formatDate(date1, 'YYYY-MM-DD'));
  const d2 = new Date(formatDate(date2, 'YYYY-MM-DD'));
  const diffTime = Math.abs(d2 - d1);
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
};

/**
 * 获取相对时间描述（今天、昨天、明天等）
 */
export const getRelativeTime = (date) => {
  const today = new Date(getToday());
  const targetDate = new Date(formatDate(date, 'YYYY-MM-DD'));
  const diffDays = getDaysDiff(today, targetDate);
  
  if (diffDays === 0) return '今天';
  if (diffDays === 1) {
    return targetDate > today ? '明天' : '昨天';
  }
  if (diffDays === 2) {
    return targetDate > today ? '后天' : '前天';
  }
  
  return formatDate(date, 'YYYY-MM-DD');
};

/**
 * 判断是否为周末（周六或周日）
 * @param {Date|string} date - 日期对象或日期字符串
 * @returns {boolean} 是否为周末
 */
export const isWeekend = (date) => {
  const d = date instanceof Date ? date : new Date(formatDate(date, 'YYYY-MM-DD'));
  const day = d.getDay();
  return day === 0 || day === 6; // 0 = 周日, 6 = 周六
};

/**
 * 获取明天的日期字符串
 * @returns {string} 明天的日期 (YYYY-MM-DD)
 */
export const getTomorrow = () => {
  const tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  return formatDate(tomorrow, 'YYYY-MM-DD');
};

/**
 * 获取昨天的日期字符串
 * @returns {string} 昨天的日期 (YYYY-MM-DD)
 */
export const getYesterday = () => {
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  return formatDate(yesterday, 'YYYY-MM-DD');
};

/**
 * 获取本周的所有日期
 * @param {Date} date - 基准日期，默认为今天
 * @param {string} weekStartDay - 周起始日，'sunday' 或 'monday'
 * @returns {Array<{date: string, dayName: string}>} 日期数组，包含日期字符串和星期名称
 */
export const getWeekDates = (date = new Date(), weekStartDay = 'monday') => {
  const weekRange = getWeekRange(date, weekStartDay);
  const startDate = new Date(weekRange.weekStart);
  const dates = [];
  const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
  
  for (let i = 0; i < 7; i++) {
    const currentDate = new Date(startDate);
    currentDate.setDate(startDate.getDate() + i);
    const dateStr = formatDate(currentDate, 'YYYY-MM-DD');
    const dayIndex = currentDate.getDay();
    dates.push({
      date: dateStr,
      dayName: dayNames[dayIndex],
    });
  }
  
  return dates;
};

/**
 * 获取月份内所有的周
 * @param {string} month - 月份字符串 (YYYY-MM)
 * @param {string} weekStartDay - 周起始日，'sunday' 或 'monday'
 * @returns {Array<{weekNumber: number, weekStart: string, weekEnd: string, dates: Array<{date: string, dayName: string}>}>} 周数组
 */
export const getMonthWeeks = (month, weekStartDay = 'monday') => {
  const [year, monthNum] = month.split('-').map(Number);
  const firstDay = new Date(year, monthNum - 1, 1);
  const lastDay = new Date(year, monthNum, 0); // 月份的最后一天
  
  const weeks = [];
  
  // 找到月份第一周的标准开始日期（可能在上个月）
  const firstWeekRange = getWeekRange(firstDay, weekStartDay);
  let weekStart = new Date(firstWeekRange.weekStart);
  
  // 周序号从1开始
  let weekNumber = 1;
  
  // 遍历所有包含月份日期的周
  // 从包含月份第一天的周开始，直到周不再包含月份内的日期
  while (true) {
    const weekEnd = new Date(weekStart);
    weekEnd.setDate(weekStart.getDate() + 6);
    
    // 检查这一周是否包含月份内的日期
    // 如果周的开始或结束日期在月份范围内，或者周跨越了月份范围
    const containsMonthDates = (weekStart >= firstDay && weekStart <= lastDay) ||
                               (weekEnd >= firstDay && weekEnd <= lastDay) ||
                               (weekStart < firstDay && weekEnd > lastDay);
    
    if (!containsMonthDates && weekStart > lastDay) {
      // 如果周开始日期已经超过月份最后一天，且不包含月份日期，则停止
      break;
    }
    
    // 获取这一周的所有日期（只包含在月份内的）
    const dates = [];
    const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    for (let i = 0; i < 7; i++) {
      const date = new Date(weekStart);
      date.setDate(weekStart.getDate() + i);
      
      // 只包含在月份内的日期
      if (date >= firstDay && date <= lastDay) {
        const dateStr = formatDate(date, 'YYYY-MM-DD');
        const dayIndex = date.getDay();
        dates.push({
          date: dateStr,
          dayName: dayNames[dayIndex],
        });
      }
    }
    
    // 只有当这一周包含月份内的日期时才添加
    if (dates.length > 0) {
      // 使用标准的周结束日期（可能在下个月）
      const standardWeekEnd = new Date(weekStart);
      standardWeekEnd.setDate(weekStart.getDate() + 6);
      
      weeks.push({
        weekNumber,
        weekStart: formatDate(weekStart, 'YYYY-MM-DD'),
        weekEnd: formatDate(standardWeekEnd, 'YYYY-MM-DD'), // 使用标准的周结束日期
        dates,
      });
    }
    
    // 移动到下一周
    weekStart.setDate(weekStart.getDate() + 7);
    weekNumber++;
    
    // 如果下一周的开始日期已经超过月份最后一天，检查是否还包含月份日期
    if (weekStart > lastDay) {
      const nextWeekEnd = new Date(weekStart);
      nextWeekEnd.setDate(weekStart.getDate() + 6);
      // 如果下一周不包含月份日期，则停止
      if (!(nextWeekEnd >= firstDay)) {
        break;
      }
    }
  }
  
  return weeks;
};

